function [best,xm,fv] = LnCPSO(fitness,N,M,D)

%       base PSO

%c1 = 2;    %废除原来的学习因子固定的方式
%c2 = 2;
w = 0.8;
cmax = 2;
cmin = 1;

%---------参数说明-----------------
%   fitness ： 目标函数
%   N ：  粒子群的种群大小，即粒子数量
%   c1:   个体学习因子（粒子自身的学习速率）
%   c2：  社会学习因子（粒子向群体最优解学习的速率）
%   w ：  惯性权重，控制速度更新时对前一次速度的依赖程度
%   M ：  最大迭代次数
%   D ：  问题的维度（即粒子的位置向量的维度）

%----------返回值说明--------------
%   xm：全局最优解
%   fv：全局最优解对应的目标函数值


%   MATLAB 中的一条命令，用于设置数值显示格式。其目的是控制 MATLAB 命令窗口中数值的显示精度。

format long;

%初始化种群的个体

for i = 1 : N
    for j = 1 : D

        %  randn matlab自带的函数
        %  randn 用于产生标准正态分布的随机数或者矩阵
        %  randn 输入参数，randn(n) 则产生一个随机数矩阵，
        %        如果没有输入参数，则表示产生一个随机数
        
        % x 为位置矩阵 维度为N * D 
        x(i,j) = randn; %随机初始化位置

        % v 为速度矩阵 维度为N * D
        v(i,j) = randn;

    end
end


%------------先计算各个粒子的适应度，并初始化Pi 和 Pg----------

%Pi ： 个体最佳位置
%pg ： 全局最佳位置

for i = 1 : N

    p(i) = fitness(x(i,:));
    % x(i,:) 表示第 i 个粒子的位置向量。x 是一个二维矩阵，每一行代表粒子 i 的位置，
    %        每一列对应一个维度的坐标，x(i,:) 表示取出第 i个粒子在所有维度上的位置。
    %fitness ：是一个函数句柄，用于计算粒子在当前位置的适应度值，目标是最小或者最大化的该适应度值。
    %p(i)    : 一个向量，存储每个粒子的个体最佳适应度值。
    %y(i,:)  : 一个矩阵，用于存储粒子的位置，将x赋值给y,用于存储个体最优解


    y(i,:) = x(i,:);    % 用于存储每个粒子的最优解的坐标

end

pg = x(N,:);    %pg 为全局最优解
                %取出位置矩阵 x 的第 N 行，即第 N 个粒子的当前位置。这里的 : 表示取出该行的所有列。换句话说，这将得到第 N 个粒子的所有维度的当前位置。
                %由于pg在后续的算法迭代中会被更新，所以初始值可以从任意一个粒子的当前位置开始，这里选择了第N个粒子的当前位置作为初始全局最优位置。
     
for i = 1 : (N - 1)

    %Pg 会表示粒子群中所有粒子位置中适应度值最低的位置，即全局最优位置。

    if fitness(x(i,:)) < fitness(pg)
        pg = x(i,:);
    end
end

%% ------------进入主要循环，按照公式依次迭代--------------------

for t= 1 : M    %进行迭代，迭代次数为 M 次

    c = cmax - (cmax - cmin) * t / M;

    for i = 1 : N   %每一次迭代对种群所有粒子（N个）进行更新
 
        % 速度更新公式
        %其中 rand 表示随机权重
        v(i,:) = w*v(i,:) + c * rand *(y(i,:) - x(i,:)) + c * rand * (pg - x(i,:));
        %个体位置更新
        x(i,:) = x(i,:) + v(i,:);
       
        %更新后的位置如果适应度优于之前的个体最佳适应度，则更新个体最佳位置。
        if fitness(x(i,:)) < p(i)
            p(i) = fitness(x(i,:)); %个体在最优坐标位置下的函数值
            y(i,:) = x(i,:);        %个体的当前最优位置
            
            
        end
        %如果个体最佳适应度优于全局最佳适应度，则更新全局最佳位置pg。
        if p(i) < fitness(pg)
           pg = y(i,:);
        end
    end
   
    % pbest记录每次迭代的全局最佳适应位置
    pbest(t) = fitness(pg);
   
end
    
    best = pbest;
    %循环结束后，返回全局最佳位置（坐标）xm和对应的目标函数的最优解fv
    %xm ： x matrix min
    %fv ： function value
    xm = pg';
    % ' : 转置操作符，用于将向量或矩阵进行转置。
    fv = fitness(pg);
end

